home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Applications
/
NeuroSim 1.0
/
Slider ƒ
/
Slider.cp
next >
Wrap
Text File
|
1996-02-19
|
28KB
|
925 lines
//
// ===========================================================================
// Slider.cp ©1994 Scott Squires
// ===========================================================================
//
// ***
// *** NOTE: The HorzSlider::GetSliderValue function has been MODIFIED.
// *** I'm distributing this modified version with Scott's permission.
// ***
// *** Timo Eloranta (02/19/1996)
// ***
/*
HorzSlider and VertSlider are classes for PowerPlant that provide a movable
slider similar to setting the volume control on the Mac. I wrote these classes
over a year ago with CW DR1 or 2.
Rather than dealing with CDEFs these classes can be compiled and used directly in
your program and easily subclassed or modified for new behavior. This makes
tracking action very easy.
I'm posting this as freeware (but still copyrighted) for people to use as they
like.
Scott Squires
Internet: squires@crl.com
AOL: ScottSquir
CompuServe: 76545,573
Usage:
Create a Base or background picture for your slider and save it as a PICT
resource. Create a Slider picture for your slider and save it as a PICT resource.
This should be smaller than your base picture.
PPob Version:
Using Window PPob with Slider built in:
Create Window/view PPob with subviews of Hsld or Vsld. You can do this in
PowerPlant Constructor by creating a view and changing it's type name to
Hsld or Vsld.
// In App constructor register these classes
URegistrar::RegisterClass(HorzSlider::class_ID, HorzSlider::CreateHorzSliderStream);
URegistrar::RegisterClass(VertSlider::class_ID, VertSlider::CreateVertSliderStream);
// after loading a PPob window with Sliders
HorzSlider * theSlider = (HorzSlider *)theView->FindPaneByID(2006);
theSlider->SetPicts(128,129); // Pict ResID 128 is base
// Pict ResID 129 is slider
theSlider->SetMinMax(0,1000); // sets value range
theSlider->SetValueMessage(2006); // In your view listen for this msg
if (theSlider->MakeSlider()) // Do the actual building of slider
theSlider->AddListener(theView);
else
delete theSlider; // delete if couldn't be created
Run Time Version:
// assumes you've created window and theView
HorzSlider *theSlider = new HorzSlider(128,129); // Pict ResID 128 is base
// Pict ResID 129 is slider
theSlider->PutInside(theView);
theSlider->SetMinMax(0,1000); // sets value range
theSlider->SetValueMessage(2006); // In your view listen for this msg
if (theSlider->MakeSlider()) // Do the actual building of slider
theSlider->AddListener(theView);
else
delete theSlider; // delete if couldn't be created
// In your view/listener do something like this:
void MyView::ListenToMessage(MessageT inMessage, void *ioParam)
{
switch (inMessage) {
// Message sent from Slider when value is updated
case 2006:
NumToString(*(long *)ioParam, theNum);
SetRect(&box, 215, 10, 245, 30);
TextBox(theNum + 1, theNum[0], &box, teFlushRight);
break;
}
}
Under the Hood:
Slider is an abstract class based on LView and LBroadcaster. HorzSlider and
VertSlider are built from Slider.
When a slider object is created default values are set. During MakeSlider() the
picture resources that were assigned are loaded and LGWorld objects are created
to hold these pictures. If a third pict is specfied it is used as a selected
slider. An additional LGWorld is created to hold the Slider image when it is
updated.
The slider is resized to match the actual size of the base picture.
When a slider is clicked on the selected slider is displayed if one was
specified. The mouse is then tracked and the slider is continuously updated. For
each update a Message is broadcast to any listeners with the new value.
DrawSelf() for the slider copies the GWorld with the base picture to the
work GWorld. The slider or selected slider is then copied to this as well.
Finally the work GWorld is copied to the screen.
Misc Notes:
Slider pictures are assumed to be smaller than the base pictures.
Slider pictures can be offset within a base picture.
The Selected slider picture is assumed to be the same size as the normal slider.
Sliders are dealt with as rectangular objects. You can still simulate an
irregular image.
Slider values are signed longs so can be quite large.
The LGWorlds are created with the deepest depth. This allows the best speed for
updates. You could change this to 8 bits (256 colors) if memory will be tight.
If you click on the base picture and not the actual slider the slider will move
instantly to that position.
Sliders have a flag that can cause the cursor to be hidden while tracking.
Sliders also have a flag that can just activate the slider, not the base picture.
Any window that Sliders are added to should be hidden until the MakeSlider() is
executed.
MakeSlider() was factored out of the constructor to avoid memory problems in a
constructor and to provide a little more flexibility.
Future:
Feel free to improve, subclass, or modify.
These are based on LView class to allow more flexibility but could be based on
LPane without problems.
Rather than being based on LView these could be created from LControl with
simularities to controls. (min, max, values, etc)
Slider PPobs are just LViews renamed/typed. As such the create from stream
functions don't contain any more data than an LView would. Future versions of
PowerPlant Constructor might make it easier to add the pict IDs and other values.
I had planned to implement 'dirty rectangles' to make the updates faster but that
hasn't proved necessary for my uses. This could be done by creating a function
similar to DrawSelf that would be called while tracking. Rather than copying the
entire base GWorld over just the rectangle where the slider used to be would be
copied to the temp GWorld. The slider would be copied like usual and then the
GWorld to window copy would only copy a rectangle that would cover the old and
new slider rectangle. (small if updated quickly)
Regions could be used for checking clicks and for copying irregular images.
Create a temp GWorld 1 bit deep, draw slider pict and then use BitMapToRegion.
You could provide B&W and color picts and have correct versions loaded depending
on screen depth.
*/
#include "Slider.h"
#include <UGWorld.h>
#include <PP_Messages.h>
// ---------------------------------------------------------------------------
// • SetDefaults
// ---------------------------------------------------------------------------
// Init values in a slider
void Slider::SetDefaults(void)
{
mBasePictID = resID_Undefined;
mSliderPictID = resID_Undefined;
mSliderSelectPictID = resID_Undefined;
SetRect(&mBasePictRect, 0, 0, 100, 25);
SetRect(&mSliderRect, 0, 0, 25, 25);
mMinSliderValue = 0;
mMaxSliderValue = 100;
mSelected = false;
mSliderCursor = true;
mBaseGWorld = nil;
mSliderGWorld = nil;
mSliderSelectGWorld = nil;
mWorkGWorld = nil;
mSliderOnly = false;
}
// ---------------------------------------------------------------------------
// • Slider
// ---------------------------------------------------------------------------
// Default Constructor
Slider::Slider()
{
SetDefaults();
}
// ---------------------------------------------------------------------------
// • Slider(ResIDT mBasePictRes, ResIDT mSliderPictRes)
// ---------------------------------------------------------------------------
// Create Slider and assign Pict resource numbers
Slider::Slider(ResIDT BasePictRes, ResIDT SliderPictRes)
{
SetDefaults();
mBasePictID = BasePictRes;
mSliderPictID = SliderPictRes;
}
// ---------------------------------------------------------------------------
// • Slider(ResIDT mBasePictRes, ResIDT mSliderPictRes, ResIDT SlideSelectPictRes)
// ---------------------------------------------------------------------------
// Create Slider including selected slider and assign Pict resource numbers
Slider::Slider(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
{
SetDefaults();
mBasePictID = BasePictRes;
mSliderPictID = SliderPictRes;
mSliderSelectPictID = SlideSelectPictRes;
}
// ---------------------------------------------------------------------------
// • Slider(LStream*)
// ---------------------------------------------------------------------------
// Construct Slider from data in a Stream
Slider::Slider(LStream *inStream)
: LView(inStream)
{
SetDefaults();
}
// ---------------------------------------------------------------------------
// • ~Slider
// ---------------------------------------------------------------------------
// Destructor, deletes any LGWorld objects created
Slider::~Slider(void)
{
if (mBaseGWorld)
delete mBaseGWorld;
if (mWorkGWorld)
delete mWorkGWorld;
if (mSliderGWorld)
delete mSliderGWorld;
if (mSliderSelectGWorld)
delete mSliderSelectGWorld;
}
// ---------------------------------------------------------------------------
// • MakeSlider
// ---------------------------------------------------------------------------
// Loads PICT resources, creates LGWorlds, and draw pictures into LGWorlds
Boolean Slider::MakeSlider(void)
{
PicHandle macPictureH = ::GetPicture(mBasePictID);
if (macPictureH != nil) { // Use PICT if found
mBasePictRect = (*macPictureH)->picFrame;
OffsetRect(&mBasePictRect, -mBasePictRect.left, -mBasePictRect.top);
mBaseLength = mBasePictRect.right;
mBaseHeight = mBasePictRect.bottom;
// Adjust Pane size
ResizeFrameTo(mBasePictRect.right, mBasePictRect.bottom, false);
mBaseGWorld = new LGWorld(mBasePictRect, 0, 0, 0, 0); // Make GWorld
if (mBaseGWorld) { // draw the picture
mBaseGWorld->BeginDrawing();
::DrawPicture(macPictureH, &mBasePictRect);
mBaseGWorld->EndDrawing();
mWorkGWorld = new LGWorld(mBasePictRect, 0, 0, 0, 0);
if (mWorkGWorld) {
mWorkGWorld->BeginDrawing();
::DrawPicture(macPictureH, &mBasePictRect);
mWorkGWorld->EndDrawing();
}
}
ReleaseResource( (Handle)macPictureH );
}
// Get Slider picture and make LGWorld
macPictureH = ::GetPicture(mSliderPictID);
if (macPictureH != nil) {
mSliderRect = (*macPictureH)->picFrame;
OffsetRect(&mSliderRect, -mSliderRect.left, -mSliderRect.top);
mBaseLength = mBaseLength - (mSliderRect.right - mSliderRect.left);
mBaseHeight = mBaseHeight - (mSliderRect.bottom - mSliderRect.top);
mSliderGWorld = new LGWorld(mSliderRect, 0, 0, 0, 0);
if (mSliderGWorld) {
mSliderGWorld->BeginDrawing();
::DrawPicture(macPictureH, &mSliderRect);
mSliderGWorld->EndDrawing();
}
ReleaseResource( (Handle)macPictureH );
}
if (mSliderSelectPictID != resID_Undefined) // load and setup Selected pict if defined
{
macPictureH = ::GetPicture(mSliderSelectPictID);
if (macPictureH != nil) {
mSliderSelectGWorld = new LGWorld(mSliderRect, 0, 0, 0, 0);
if (mSliderSelectGWorld) {
mSliderSelectGWorld->BeginDrawing();
::DrawPicture(macPictureH, &mSliderRect);
mSliderSelectGWorld->EndDrawing();
}
ReleaseResource( (Handle)macPictureH );
}
}
// true if all needed picts found and GWorlds created
return ((mBaseGWorld && mSliderGWorld && mWorkGWorld)
&& ((mSliderSelectPictID == resID_Undefined) || mSliderSelectGWorld));
}
// ---------------------------------------------------------------------------
// • SetPicts
// ---------------------------------------------------------------------------
// Defines PICT resource numbers for base and slider, no Selected slider
void Slider::SetPicts(ResIDT BasePictRes, ResIDT SliderPictRes)
{
mBasePictID = BasePictRes;
mSliderPictID = SliderPictRes;
}
// ---------------------------------------------------------------------------
// • SetPicts
// ---------------------------------------------------------------------------
// Defines PICT resource numbers for base, slider, and Selected slider
void Slider::SetPicts(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
{
mBasePictID = BasePictRes;
mSliderPictID = SliderPictRes;
mSliderSelectPictID = SlideSelectPictRes;
}
// ---------------------------------------------------------------------------
// • OffsetSlider
// ---------------------------------------------------------------------------
// Move Slider relative to base picture. Used when slider is smaller tan base picture
void Slider::OffsetSlider(short Xoffset, short Yoffset)
{
OffsetRect(&mSliderRect, Xoffset, Yoffset);
}
// ---------------------------------------------------------------------------
// • DrawSelf
// ---------------------------------------------------------------------------
// Draw the Slider
void Slider::DrawSelf()
{
GrafPtr savePort;
GetPort(&savePort);
::PenNormal();
if (mBaseGWorld && mWorkGWorld) {
// copy base GWorld to temp GWorld
mWorkGWorld->BeginDrawing();
mBaseGWorld->CopyImage((GrafPtr)mWorkGWorld->GetMacGWorld(), mBasePictRect, srcCopy, 0);
mWorkGWorld->EndDrawing();
}
if (mSelected && mSliderSelectGWorld) // Is it selected and does a Select LGWorld exist?
{
if (mSliderSelectGWorld && mWorkGWorld) {
// copy Select slider GWorld to temp GWorld
mWorkGWorld->BeginDrawing();
mSliderSelectGWorld->CopyImage((GrafPtr)mWorkGWorld->GetMacGWorld(), mSliderRect, srcCopy, 0);
mWorkGWorld->EndDrawing();
}
} else {
if (mSliderGWorld && mWorkGWorld) {
// copy slider GWorld to temp GWorld
mWorkGWorld->BeginDrawing();
mSliderGWorld->CopyImage((GrafPtr)mWorkGWorld->GetMacGWorld(), mSliderRect, srcCopy, 0);
mWorkGWorld->EndDrawing();
}
}
if (mWorkGWorld) {
mWorkGWorld->CopyImage(savePort, mBasePictRect, srcCopy, 0);// display it
} else {
FrameRect(&mBasePictRect); // If all else fails, draw a box
}
}
// ---------------------------------------------------------------------------
// • PointInSlider
// ---------------------------------------------------------------------------
// Check to see if a point is within the slider rect
Boolean Slider::PointInSlider(Point thePoint)
{
return (PtInRect(thePoint, &mSliderRect));
}
// ---------------------------------------------------------------------------
// • SetMinMax
// ---------------------------------------------------------------------------
// Set min and max values for slider, long values
void Slider::SetMinMax(long theMin, long theMax)
{
mMinSliderValue = theMin;
mMaxSliderValue = theMax;
if(IsVisible())
{
SetSliderValue(mValue); // clamp existing value and redraw
}
}
// ---------------------------------------------------------------------------
// • DoAction
// ---------------------------------------------------------------------------
// Send message if new value
void Slider::DoAction(void)
{
long tempValue;
tempValue = GetSliderValue();
if (mValue != tempValue) {
// only send message if true value changed
mValue = tempValue;
BroadcastValueMessage();
}
}
// ---------------------------------------------------------------------------
// • BroadcastValueMessage
// ---------------------------------------------------------------------------
// Send message with value
void Slider::BroadcastValueMessage()
{
if (mValueMessage != cmd_Nothing) {
Int32 value = mValue;
BroadcastMessage(mValueMessage, (void *) & value);
}
}
// ---------------------------------------------------------------------------
// • SetValueMessage
// ---------------------------------------------------------------------------
// Assign Message number
void Slider::SetValueMessage(MessageT inValueMessage)
{
mValueMessage = inValueMessage;
}
// ---------------------------------------------------------------------------
// • GetValueMessage
// ---------------------------------------------------------------------------
// Return Message number
MessageT Slider::GetValueMessage() const
{
return mValueMessage;
}
// ---------------------------------------------------------------------------
// • SetCursorFlag
// ---------------------------------------------------------------------------
// If true then display cursor, false hides cursor when tracking
void Slider::SetCursorFlag(Boolean theFlag)
{
mSliderCursor = theFlag;
}
// ---------------------------------------------------------------------------
// • SetSliderOnlyFlag
// ---------------------------------------------------------------------------
// If true then activate only when slider hit, false makes the whole base pciture active
void Slider::SetSliderOnlyFlag(Boolean theFlag)
{
mSliderOnly = theFlag;
}
// ---------------------------------------------------------------------------
// • HorzSlider
// ---------------------------------------------------------------------------
// Default Constructor
HorzSlider::HorzSlider()
: Slider()
{
}
// ---------------------------------------------------------------------------
// • HorzSlider(ResIDT BasePictRes, ResIDT mSliderPictRes)
// ---------------------------------------------------------------------------
// Create Horizontal Slider and assign Pict resource numbers
HorzSlider::HorzSlider(ResIDT BasePictRes, ResIDT SliderPictRes)
: Slider(BasePictRes, SliderPictRes)
{
}
// ---------------------------------------------------------------------------
// • HorzSlider(ResIDT BasePictRes, ResIDT mSliderPictRes, ResIDT SlideSelectPictRes))
// ---------------------------------------------------------------------------
// Create Horizontal Slider and assign Pict resource numbers
HorzSlider::HorzSlider(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
: Slider(BasePictRes, SliderPictRes, SlideSelectPictRes)
{
}
// ---------------------------------------------------------------------------
// • HorzSlider(LStream*)
// ---------------------------------------------------------------------------
// Construct HorzSlider from data in a Stream
HorzSlider::HorzSlider(LStream *inStream)
: Slider(inStream)
{
}
// ---------------------------------------------------------------------------
// • CreateHorzSliderStream [static]
// ---------------------------------------------------------------------------
// Return a new HorzSlider object initialized using data from a Stream
HorzSlider *HorzSlider::CreateHorzSliderStream(LStream *inStream)
{
return (new HorzSlider(inStream));
}
// ---------------------------------------------------------------------------
// • ~HorzSlider
// ---------------------------------------------------------------------------
// Destructor, deletes any LGWorld objects created
HorzSlider::~HorzSlider()
{
}
// ---------------------------------------------------------------------------
// • TrackSlider
// ---------------------------------------------------------------------------
// Move slider while mouse button is down
// Calls DoAction() when moving
void HorzSlider::TrackSlider(Point oldMouse)
{
Point newMouse;
mSelected = true;
if (!mSliderCursor)
HideCursor(); // Hide cursor if mSliderCursor is false
while (Button()) {
GetMouse(&newMouse);
if (!EqualPt(newMouse, oldMouse)) {
// Mouse moved?
if (((newMouse.h > mBasePictRect.left) || (mSliderRect.left > mBasePictRect.left))
&& ((newMouse.h < mBasePictRect.right) || (mSliderRect.right < mBasePictRect.right))) {
// Move slider if mouse within base picture area
OffsetRect(&mSliderRect, newMouse.h - oldMouse.h, 0);
// Keep Slider from going too far
if (mSliderRect.right > mBasePictRect.right)
OffsetRect(&mSliderRect, mBasePictRect.right - mSliderRect.right, 0);
if (mSliderRect.left < mBasePictRect.left)
OffsetRect(&mSliderRect, mBasePictRect.left - mSliderRect.left, 0);
oldMouse = newMouse;
DrawSelf();
DoAction(); // Send message
FocusDraw();
}
}
oldMouse = newMouse;
}
mSelected = false;
DrawSelf(); // Display again without selection
ShowCursor(); // Display cursor in case it was hidden
}
// ---------------------------------------------------------------------------
// • ClickSelf
// ---------------------------------------------------------------------------
// Move slider while mouse button is down
// Calls DoAction() when moving
void HorzSlider::ClickSelf(const SMouseDownEvent &inMouseDown)
{
if (PointInSlider(inMouseDown.whereLocal)) {
// click in slider?
FocusDraw();
mSelected = true;
DrawSelf(); // update as selected
TrackSlider(inMouseDown.whereLocal);
} else {
if (PtInRect(inMouseDown.whereLocal, &mBasePictRect)&&(!mSliderOnly)) {
// click in base?
// Move Slider to center on mouse
OffsetRect(&mSliderRect, (inMouseDown.whereLocal.h - mSliderRect.left -
((mSliderRect.right - mSliderRect.left) / 2)), 0);
// Keep slider in base pict
if (mSliderRect.right > mBasePictRect.right)
OffsetRect(&mSliderRect, mBasePictRect.right - mSliderRect.right, 0);
if (mSliderRect.left < mBasePictRect.left)
OffsetRect(&mSliderRect, mBasePictRect.left - mSliderRect.left, 0);
mSelected = true;
FocusDraw();
DrawSelf();
DoAction(); // Send message
// now track it
FocusDraw();
TrackSlider(inMouseDown.whereLocal);
}
}
}
// ---------------------------------------------------------------------------
// • GetSliderValue ( !!! MODIFIED !!! )
// ---------------------------------------------------------------------------
// Return value of slider
long HorzSlider::GetSliderValue(void)
{
long total;
float tempvalue;
total = (mMaxSliderValue - mMinSliderValue);
// tempvalue = ((float)total / (float)(mBaseLength)) *
// (mSliderRect.left - mBasePictRect.left); // Original
tempvalue = ((float)total / (float)(mBaseLength)) *
(mSliderRect.left - mBasePictRect.left + 1); // TE 8/31/95
return (tempvalue + mMinSliderValue);
}
// ---------------------------------------------------------------------------
// • SetSliderValue
// ---------------------------------------------------------------------------
// Set value of slider, update display and send message
void HorzSlider::SetSliderValue(long theValue)
{
long total;
float tempvalue;
total = (mMaxSliderValue - mMinSliderValue);
if (theValue < mMinSliderValue) theValue = mMinSliderValue;
if (theValue > mMaxSliderValue) theValue = mMaxSliderValue;
tempvalue = ((float)(theValue- mMinSliderValue)/(float)total) * (mBaseLength);
OffsetRect(&mSliderRect,-mSliderRect.left,0);
OffsetRect(&mSliderRect,tempvalue,0);
FocusDraw();
DrawSelf();
DoAction(); // Send message
}
// ---------------------------------------------------------------------------
// • VertSlider
// ---------------------------------------------------------------------------
// Default Constructor
VertSlider::VertSlider()
: Slider()
{
}
// ---------------------------------------------------------------------------
// • VertSlider(ResIDT BasePictRes, ResIDT SliderPictRes)
// ---------------------------------------------------------------------------
// Create Vertical Slider and assign Pict resource numbers
VertSlider::VertSlider(ResIDT BasePictRes, ResIDT SliderPictRes)
: Slider(BasePictRes, SliderPictRes)
{
}
// ---------------------------------------------------------------------------
// • VertSlider(ResIDT BasePictRes, ResIDT mSliderPictRes, ResIDT SlideSelectPictRes))
// ---------------------------------------------------------------------------
// Create Vertical Slider and assign Pict resource numbers
VertSlider::VertSlider(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
: Slider(BasePictRes, SliderPictRes, SlideSelectPictRes)
{
}
// ---------------------------------------------------------------------------
// • VertSlider(LStream*)
// ---------------------------------------------------------------------------
// Construct VertSlider from data in a Stream
VertSlider::VertSlider(LStream *inStream)
: Slider(inStream)
{
}
// ---------------------------------------------------------------------------
// • CreateVertSliderStream [static]
// ---------------------------------------------------------------------------
// Return a new VertSlider object initialized using data from a Stream
VertSlider *VertSlider::CreateVertSliderStream(LStream *inStream)
{
return (new VertSlider(inStream));
}
// ---------------------------------------------------------------------------
// • ~VertSlider
// ---------------------------------------------------------------------------
// Destructor, deletes any LGWorld objects created
VertSlider::~VertSlider()
{
}
// ---------------------------------------------------------------------------
// • TrackSlider
// ---------------------------------------------------------------------------
// Move slider while mouse button is down
// Calls DoAction() when moving
void VertSlider::TrackSlider(Point oldMouse)
{
Point newMouse;
mSelected = true;
if (!mSliderCursor)
HideCursor();
while (Button()) {
GetMouse(&newMouse);
if (!EqualPt(newMouse, oldMouse)) {
// Mouse moved?
if (((newMouse.v > mBasePictRect.top) || (mSliderRect.top > mBasePictRect.top)) &&
((newMouse.v < mBasePictRect.bottom) || (mSliderRect.bottom < mBasePictRect.bottom))) {
// Move Slider if mouse in base picture area
OffsetRect(&mSliderRect, 0, newMouse.v - oldMouse.v);
if (mSliderRect.bottom > mBasePictRect.bottom)
OffsetRect(&mSliderRect, 0, mBasePictRect.bottom - mSliderRect.bottom);
if (mSliderRect.top < mBasePictRect.top)
OffsetRect(&mSliderRect, 0, mBasePictRect.top - mSliderRect.top);
oldMouse = newMouse;
DrawSelf();
DoAction(); // Send message
FocusDraw();
}
}
oldMouse = newMouse;
}
mSelected = false;
DrawSelf(); // update without selection
ShowCursor(); // Show cursor in case it was hidden
}
// ---------------------------------------------------------------------------
// • ClickSelf
// ---------------------------------------------------------------------------
// Move slider while mouse button is down
// Calls DoAction() when moving
void VertSlider::ClickSelf(const SMouseDownEvent &inMouseDown)
{
if (PointInSlider(inMouseDown.whereLocal)) {
// click in slider?
FocusDraw();
mSelected = true;
DrawSelf();
TrackSlider(inMouseDown.whereLocal);
} else {
if (PtInRect(inMouseDown.whereLocal, &mBasePictRect)&&(!mSliderOnly)) {
// click in base?
FocusDraw();
mSelected = true;
OffsetRect(&mSliderRect, 0, (inMouseDown.whereLocal.v - mSliderRect.top - ((mSliderRect.bottom - mSliderRect.top
) / 2)));
if (mSliderRect.bottom > mBasePictRect.bottom)
OffsetRect(&mSliderRect, 0, mBasePictRect.bottom - mSliderRect.bottom);
if (mSliderRect.top < mBasePictRect.top)
OffsetRect(&mSliderRect, 0, mBasePictRect.top - mSliderRect.top);
DrawSelf();
DoAction();
// now track it
FocusDraw();
TrackSlider(inMouseDown.whereLocal);
}
}
}
// ---------------------------------------------------------------------------
// • GetSliderValue
// ---------------------------------------------------------------------------
// Return value of slider
long VertSlider::GetSliderValue(void)
{
long total;
float tempvalue;
total = (mMaxSliderValue - mMinSliderValue);
tempvalue = ((float)total / (float)(mBaseHeight)) * (mSliderRect.top - mBasePictRect.top);
return (tempvalue + mMinSliderValue);
}
// ---------------------------------------------------------------------------
// • SetSliderValue
// ---------------------------------------------------------------------------
// Set value of slider, update display and send message
void VertSlider::SetSliderValue(long theValue)
{
long total;
float tempvalue;
total = (mMaxSliderValue - mMinSliderValue);
if (theValue < mMinSliderValue) theValue = mMinSliderValue;
if (theValue > mMaxSliderValue) theValue = mMaxSliderValue;
tempvalue = ((float)(theValue- mMinSliderValue)/(float)total) * mBaseHeight;
OffsetRect(&mSliderRect,0,-mSliderRect.top);
OffsetRect(&mSliderRect,0,tempvalue);
FocusDraw();
DrawSelf();
DoAction(); // Send message
}